from flask import Flask, render_template, request
from flask_socketio import SocketIO, emit
import time
from threading import Lock

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

# 游戏状态
game_state = {
    'players': {
        1: {'remaining_time': 180, 'running': False},
        2: {'remaining_time': 180, 'running': False},
        3: {'remaining_time': 180, 'running': False}
    },
    'current_player': 1,
    'last_update': time.time()
}

# 线程锁
thread_lock = Lock()


def background_timer():
    """后台计时线程"""
    while True:
        with thread_lock:
            current_time = time.time()
            elapsed = current_time - game_state['last_update']
            game_state['last_update'] = current_time

            # 更新当前玩家的时间
            current_player = game_state['current_player']
            if game_state['players'][current_player]['running']:
                game_state['players'][current_player]['remaining_time'] -= elapsed

                # 检查时间是否用完
                if game_state['players'][current_player]['remaining_time'] <= 0:
                    game_state['players'][current_player]['remaining_time'] = 0
                    game_state['players'][current_player]['running'] = False
                    socketio.emit('timer_end', {'player': current_player})

                # 广播当前状态给所有客户端
                socketio.emit('game_update', {
                    'players': game_state['players'],
                    'current_player': game_state['current_player']
                })
        socketio.sleep(0.1)


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/player/<int:player_id>')
def player_page(player_id):
    if player_id not in [1, 2, 3]:
        return "Invalid player ID", 404
    return render_template(f'player{player_id}.html')


@socketio.on('connect')
def handle_connect():
    # 新客户端连接时发送当前游戏状态
    emit('game_update', {
        'players': game_state['players'],
        'current_player': game_state['current_player']
    })


@socketio.on('pause_and_switch')
def handle_pause_and_switch(data):
    print('user pause')
    with thread_lock:
        current_time = time.time()
        elapsed = current_time - game_state['last_update']
        game_state['last_update'] = current_time

        print(
            f"Before switch - Current player: {game_state['current_player']}, Players state: {game_state['players']}")

        # 停止当前玩家计时
        if game_state['current_player'] is not None:
            current_player = game_state['current_player']
            if game_state['players'][current_player]['running']:
                game_state['players'][current_player]['remaining_time'] -= elapsed
                game_state['players'][current_player]['running'] = False

        # 查找下一个有剩余时间的玩家
        next_player = None
        if game_state['current_player'] is not None:
            for i in range(1, 4):
                candidate = (game_state['current_player'] + i - 1) % 3 + 1
                if game_state['players'][candidate]['remaining_time'] > 0:
                    next_player = candidate
                    break

        if next_player is not None:
            game_state['current_player'] = next_player
            game_state['players'][next_player]['running'] = True
        else:
            game_state['current_player'] = None
            emit('all_players_finished', broadcast=True)
            print("All players have finished their time")
            return

        print(
            f"After switch - Current player: {game_state['current_player']}, Players state: {game_state['players']}")

        emit('player_switched', {
            'current_player': game_state['current_player'],
            'players': game_state['players']
        }, broadcast=True)


@socketio.on('reset_all')
def handle_reset_all():
    with thread_lock:
        for player in game_state['players']:
            game_state['players'][player]['remaining_time'] = 180
            game_state['players'][player]['running'] = False

        game_state['current_player'] = 1
        game_state['players'][1]['running'] = True
        game_state['last_update'] = time.time()

        emit('game_reset', {
            'players': game_state['players'],
            'current_player': game_state['current_player']
        }, broadcast=True)


if __name__ == '__main__':
    # 初始化游戏状态 - 第一个玩家开始计时
    game_state['players'][1]['running'] = True
    # 启动后台线程
    socketio.start_background_task(background_timer)
    socketio.run(app, debug=True, host='0.0.0.0')
